package com.jinbaoty.recyclebins.command;

import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.hoho.android.usbserial.driver.UsbSerialPort;
import com.jinbaoty.recyclebins.command.CommandParam;
import com.jinbaoty.recyclebins.server.ResponseData;
import com.jinbaoty.recyclebins.utils.HexDump;
import com.orhanobut.logger.Logger;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;

public class UsbPortUtils {
    private static boolean isRunning = false;

    public UsbPortUtils(UsbSerialPort port){
        this.port = port;
    }
    public static boolean isRunning() {
        return isRunning;
    }

    public static void setRunning(boolean running) {
        isRunning = running;
    }

    private UsbSerialPort port;

    public UsbSerialPort getPort() {
        return port;
    }

    public void setPort(UsbSerialPort port) {
        this.port = port;
    }

    public  ResponseData sendForResult(CommandParam commandParam){

        try {
            ResponseData responseData = new ResponseData();
            responseData.setMessage("");
            if (isRunning()) {
                responseData.setSuccess(false);
                responseData.setMessage("用户正在进行回收操作，请稍后！");
                return responseData;
            }
            if(port==null){
                responseData.setSuccess(false);
                responseData.setMessage("串口通信失败！");
                return responseData;
            }
            String logInfo = ("发送命令："+ JSON.toJSONString(commandParam));
            this.setRunning(true);
            boolean success = true;
            int write = port.write(new byte[]{commandParam.getCommandVal()}, 400);
            byte buffer[] = startReadData(commandParam);
            int readLen  = buffer.length;
            String returnVal = "";
            if (commandParam.getReturnType() != CommandParam.RETURN_VOID) {
                logInfo+="\n"+("返回类型："+commandParam.getReturnType()+",要求返回。");
                success = readLen > 0;
                if(success){
                    returnVal = new String(buffer,0,readLen);
                    logInfo+="\n"+("返回值长度大于0：《"+returnVal+"》");
                    if(commandParam.getCommandTag().startsWith("weight")){//称重
                        String weightStr  = returnVal;
                        weightStr = weightStr.replaceAll("[^0-9.]", "");
                        success = NumberUtil.isDouble(weightStr);
                        if(success) {
                            double weight = Double.parseDouble(weightStr);
                            if(weight>0) {
                                returnVal = NumberUtil.roundStr(weight, 3);
                            }else{
                                returnVal = "0.000";
                            }
                        }
                        logInfo+="\n"+("称重："+success+"："+returnVal);
                    }
                }
                if (commandParam.getReturnType() == CommandParam.RETURN_FORCE) {
                    if (!success) {
                        responseData.setMessage("回收操作失败：" + commandParam.getErrorMsg() + "，请联系管理员。");
                    } else {
                        String result = returnVal.replaceAll("(;+)$","");
                        String successVal = commandParam.getSuccessVal();
                        if (StrUtil.isBlank(successVal) || StrUtil.containsAnyIgnoreCase(result, successVal)) {
                            if(StrUtil.isNotBlank(commandParam.getSuccessMsg())) {
                                responseData.setMessage(commandParam.getSuccessMsg());
                            }
                        } else {
                            success = false;
                            Log.d("回收操作失败", "");
                            responseData.setMessage(responseData.getMessage()+"，回收箱指令（"+commandParam.getCommandName()+"）要求返回：（"+successVal+"），实际返回：（"+result+"）。");
                        }
                    }
                }
            }
            responseData.setSuccess(success);
            if(success) responseData.setData(returnVal);
            this.setRunning(false);
            Logger.d(logInfo);
            return responseData;
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }
    public  byte[] startReadData(CommandParam commandParam) throws IOException {
        String msg = "";
        byte buffer[] = new byte[50];
        long beginTime = System.currentTimeMillis();
        int readLen =0;
        List<Byte> returnVals = new ArrayList<>();
        msg+="发送指令：《"+commandParam.getCommandName()+"，"+ HexDump.toHexString(commandParam.getCommandVal())+"，"+commandParam.getReadRepeat()+"，"+commandParam.getWriteRepeat()+"》";
        for(int repeat=0;repeat<commandParam.getReadRepeat();repeat++) {
            msg +="【第"+(repeat+1)+"次读：";
            do {
                readLen = port.read(buffer, commandParam.getReadTimeout());
                String readVal = null;
                if (readLen > 0) {
                    String temp = "";
                    for (int i = 0; i < readLen; i++) {
                        temp += HexDump.toHexString(buffer[i]) + "(" + new String(new byte[]{buffer[i]})  + ");";
                        msg+= "《" + HexDump.toHexString(buffer[i]) + "（" + new String(new byte[]{buffer[i]}) + "）》";
                        returnVals.add(buffer[i]);
                    }

                    readVal = new String(buffer, 0, readLen);
                    //logInfo+="\n"+("第"+(repeat+1)+"次读：串口获取到的内容：" + temp + " ==> " + readVal);
                }
                if(StrUtil.endWith(readVal,";")) break;
            } while (System.currentTimeMillis() - beginTime < commandParam.getReadTimeout());
            String endReadVal = "";
            if (returnVals.size() > 0) {
                readLen = returnVals.size();
                buffer = new byte[returnVals.size()];
                for (int i = 0; i < returnVals.size(); i++) {
                    buffer[i] = returnVals.get(i);
                }
                endReadVal = new String(buffer, 0, readLen);
                //logInfo+="\n"+("第"+(repeat+1)+"次读：串口最终读取结果：" + endReadVal);
            }
            msg+=" ≡≡《" + StrUtil.blankToDefault(endReadVal,"空") + "》" + "】";
            if(CommandParam.RETURN_FORCE==commandParam.getReturnType() && !StrUtil.endWith(endReadVal,";")){
                if(repeat>0 && commandParam.getWriteRepeat()+1-repeat>0){
                    int write = port.write(new byte[]{commandParam.getCommandVal()}, 400);
                    returnVals.clear();
                    continue;
                }
            }else{
                if("weight".equals(commandParam.getCommandTag())){
                    String number = endReadVal.replaceAll("[^0-9.]", "");
                    if (!NumberUtil.isDouble(number)) {
                        int write = port.write(new byte[]{commandParam.getCommandVal()}, 400);
                        returnVals.clear();
                        continue;
                    }
                }
                break;
            }
        }
        Logger.d(msg);
        return buffer;
    }
}
